package main

import (
	"fmt"
	"io"
	"net/http"
)

/*
通过测试的启发，我们重构了代码。因为有了注入依赖，我们可以控制数据向哪儿写入，它允许我们：
测试代码。如果你不能很轻松地测试函数，这通常是因为有依赖硬链接到了函数或全局状态。
例如，如果某个服务层使用了全局的数据库连接池，这通常难以测试，并且运行速度会很慢。DI 提倡你注入一个数据库依赖（通过接口），然后就可以在测试中控制你的模拟数据了。
关注点分离，解耦了数据到达的地方和如何产生数据。如果你感觉一个方法/ 函数负责太多功能了
（生成数据并且写入一个数据库？处理HTTP 请求并且处理业务级别的逻辑），那么你可能就需要 DI 这个工具了。
在不同环境下重用代码。我们的代码所处的第一个「新」环境就是在内部进行测试。但是随后，如果其他人想要用你的代码尝试点新东西，他们只要注入他们自己的依赖就可以了。
什么是模拟？我听说 DI 要用到模拟，它可讨厌了
模拟（mocking）会在后面详细讨论（它并不坏）。你会使用模拟来代替真实事物，用一个模拟版本来注入，于是可以控制和检查你的测试。在我们的例子中，标准库已经有工具供我们使用了。
*/
func Greet(writer io.Writer, name string) {
	fmt.Fprintf(writer, "Hello,%s", name)
}

func MyGreeterHandler(w http.ResponseWriter, r *http.Request) {
	Greet(w, "world")

}

func main() {
	http.ListenAndServe(":5000", http.HandlerFunc(MyGreeterHandler))
}
